import isFunction from 'lodash/isFunction';
import isObject from 'lodash/isObject';
import merge from 'lodash/merge';
import isString from 'lodash/isString';
import isPlainObject from 'lodash/isPlainObject';
import CustomRequest from './customRequest';

const exp = /\{\{([\s\S]+?)\}\}/g;
const hasTemplate = s => s.match(exp);
const findTemplate = (s) => {
  const m = exp.exec(s);
  return m ? m[1] : '';
};

const parseTemplate = (path, param) => {
  let url = path;

  if (isString(url) && isPlainObject(param)) {
    let key = findTemplate(url);
    while (key) {
      const value = param[key] || '';
      url = url.replace(`{{${key}}}`, value);
      key = findTemplate(url);
    }
  }

  return url;
};

/**
 * 创建API实例
 * @function createAPI
 * @memberOf fe-lib.FetchRequest
 * @param method - get、post、delete等。请使用枚举FetchRequest.Consts.HttpMethods
 * @param path - resource url
 * @param fetchConfig - request config对象，包活headers， body
 * @param templateHandler - 替换url中变量的函数
 */
export default (method, path, fetchConfig, templateHandler) => (params, config) => {
  let url = path;
  let finalConfig = {};
  let finalTemplateHandler = templateHandler;

  if (isFunction(fetchConfig)) {
    finalTemplateHandler = fetchConfig;
  } else if (isObject(fetchConfig)) {
    finalConfig = fetchConfig;
  }

  if (hasTemplate(url) && !isFunction(finalTemplateHandler)) {
    finalTemplateHandler = parseTemplate;
  }

  if (isFunction(finalTemplateHandler)) {
    url = finalTemplateHandler(url, params);
  } else if (isObject(params)) {
    finalConfig = merge({}, finalConfig, params);
  }

  if (isObject(config)) {
    finalConfig = merge({}, finalConfig, config);
  }

  return CustomRequest.instance[method](url, finalConfig);
};
